﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Reflection.Metadata;
using System.Diagnostics;
using DZJIFC.Model;


#if _WIN64
using int_t = System.Int64;
#else
using int_t = System.Int32;
#endif

namespace DZJIFC.UI
{
    public partial class ModelStructureForm   : Form   , IView
    {
        #region Fields

        IController _controller;
        ContextMenuStrip _contextMenuStrip;
        Brush _selectedNodeBrush = new SolidBrush(Color.Red);

        IModelStructureView _modelStructureView;

        #endregion // Fields

        public ModelStructureForm()
        {
            InitializeComponent();
            InitializeMenu();

            _treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
        }

        private void InitializeMenu()
        {
            var zoomToMenuItem = new ToolStripMenuItem();
            zoomToMenuItem.Text = "Zoom To";
            zoomToMenuItem.Click += ZoomToMenuItem_Click;
            var zoomExtentMenuItem = new ToolStripMenuItem();
            zoomExtentMenuItem.Text = "Zoom Extent";
            zoomExtentMenuItem.Click += ZoomExtentMenuItem_Click; 

            _contextMenuStrip = new ContextMenuStrip();
            _contextMenuStrip.Items.AddRange(new ToolStripMenuItem[]{ zoomToMenuItem, zoomExtentMenuItem });
            _contextMenuStrip.Opening += ContextMenuStrip_Opening;
        }        

        void ContextMenuStrip_Opening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            var zoomToMenuItem = _contextMenuStrip.Items[0];

            var selectedInstance = _modelStructureView.GetSelectedInstance();
            if ((selectedInstance != null) && 
                selectedInstance.Enabled && 
                selectedInstance.Geometry.HasGeometry)
            {
                zoomToMenuItem.Enabled = true;
            }
            else
            {
                zoomToMenuItem.Enabled = false;
            }
            
            e.Cancel = false;
        }

        private void ZoomToMenuItem_Click(object sender, EventArgs e)
        {
            var selectedInstance = _modelStructureView.GetSelectedInstance();
            if (selectedInstance != null)
            {
                _controller.ZoomTo(selectedInstance);
            }
        }

        private void ZoomExtentMenuItem_Click(object sender, EventArgs e)
        {
            _controller.ZoomExtent();
        }

        #region IIFCView
        
        public void SetController(IController controller)
        {
            Debug.Assert(controller != null);

            _controller = controller;

            _controller.RegisterView(this);
        }

        public void OnModelLoaded()
        {
            if ((_controller != null) && (_controller.Model != null))
            {
                if (_controller.Model.Type == ModelType.AP242)
                {
                    _modelStructureView = new AP242ModelStructureView(_controller, _treeView, _contextMenuStrip);
                    _modelStructureView.OnModelLoaded();
                }
                else if (_controller.Model.Type == ModelType.IFC)
                {
                    _modelStructureView = new IFCModelStructureView(_controller, _treeView, _contextMenuStrip);
                    _modelStructureView.OnModelLoaded();
                }
                else
                {
                    Debug.Assert(false); //#todo
                }
            }            
        }

        public void OnInstanceSelected(object sender, IInstance instance)
        {
            if (sender == this)
            {
                return;
            }

            if (_modelStructureView != null)
            {
                _modelStructureView.OnInstanceSelected(sender, instance);
            }
        }

        public void OnWorldDimensionsChanged()
        {
        }

        #endregion // IIFCView

        private void TreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (_modelStructureView != null)
            {
                _modelStructureView.TreeView_OnNodeMouseClick(sender, e);
            }
        }

        private void TreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (_modelStructureView != null)
            {
                _modelStructureView.TreeView_AfterSelect(sender, e);
            }
        }
        
        private void TreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            if (_modelStructureView != null)
            {
                _modelStructureView.TreeView_BeforeExpand(sender, e);
            }
        }
        
        private void TreeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
        {
            var bSelected = (e.State & TreeNodeStates.Selected) == TreeNodeStates.Selected;
            if (bSelected)
            {                
                e.Graphics.FillRectangle(_selectedNodeBrush, e.Bounds);

                var font = e.Node.NodeFont ?? e.Node.TreeView.Font;
                TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, SystemColors.HighlightText, TextFormatFlags.GlyphOverhangPadding);
            }
            else
            {
                e.DrawDefault = true;
            }
        }

        private void ModelStructureForm_Closed(object sender, FormClosedEventArgs e)
        {
            _modelStructureView = null;

            _controller.UnRegisterView(this);
        }
    }
}
